home *** CD-ROM | disk | FTP | other *** search
- /*
- * WADFILE.C
- *
- * Version 1.0.0
- *
- * Abstract:
- * This module contains all the WADFILE processing routines for the
- * WadLib library.
- *
- * History:
- * 1.0.0 (March 31, 1994)
- *
- * Author:
- * Michael McMahon
- *
- ****************************************************************************
- * Wadfile Function Directory
- *---------------------------------------------------------------------------
- *Index: Name : Description
- *---------------------------------------------------------------------------
- * #1 : WadfileAddLump : Add a lump to a Wadfile being created.
- * #2 : WadfileClose : Close file, flush cache, update WAD directory
- * #3 : WadfileCopyEntry : Copies a lump from one Wadfile to another.
- * #4 : WadfileCopyMap : Copies a map from one Wadfile to another.
- * #5 : WadfileCreate : Create WAD file and initialize Wadfile struct.
- * #6 : WadfileGetDirInfo : Read directory info into Wadfile structure.
- * #7 : WadfileGetNextDirInfo : Move to next directory entry and read it in.
- * #8 : WadfileGetPrevDirInfo : Move to last directory entry and read it in.
- * #9 : WadfileInitialize : One-time call, set up memory allocators.
- * #10 : WadfileLumpClose : Close lump inside WAD file, free its memory.
- * #11 : WadfileLumpCopy : Copy lump file from one Wadfile to another.
- * #12 : WadfileLumpOpen : Open lump at current directory position.
- * #13 : WadfileOpen : Open a WAD file and initialize Wadfile struct.
- * #14 : WadfileSeek : Find first dir entry with a search string.
- * #15 : WadfileSeekMap : Find map given episode and map. ExMy
- ****************************************************************************
- *
- * WADLIB SOFTWARE LICENSE AGREEMENT
- *
- * 1. GRANT OF LICENSE. Michael McMahon and his affiliations (collectively
- * the "AUTHOR") grant you (either an individual or an entity) the
- * non-exclusive, royalty-free right to use this library source code,
- * documentation, and sample code (collectively, the "SOFTWARE") for
- * any lawful purpose subject to the terms of this license. By using the
- * SOFTWARE you are agreeing to be bound to all the terms of this license.
- *
- * 2. COPYRIGHT. The SOFTWARE is Copyright (c) 1994, Michael McMahon,
- * PO Box 14807, San Luis Nabisco, CA 93406-4807 USA. All Rights Reserved
- * Worldwide. You may not use, modify, or distribute the SOFTWARE except
- * as otherwise provided herein.
- *
- * 3. DECLARATION OF PUBLIC DOMAIN DISTRIBUTION AND USE. The distribution
- * and use of the SOFTWARE is hereby designated PUBLIC DOMAIN by the
- * the AUTHOR. You may not sell, rent, or lease this SOFTWARE. The
- * SOFTWARE may be reproduced verbatim in part or in full by any
- * reproduction means for any lawful purpose, and may also be subject to
- * the following agreement.
- *
- * 4. AGREEMENT FOR USE OF SOFTWARE. The AUTHOR grants you a non-exclusive,
- * royalty-free right to incorporate the SOFTWARE into any production for
- * any legal purpose as long as you agree
- * (a) to indemnify, hold harmless, and defend the AUTHOR from and against
- * any claims or lawsuits, including attorneys' fees, that arise or
- * result from the use or distribution of your software production; and
- * (b) no matter how much the SOFTWARE is modified, the AUTHOR owns the
- * copyright and this original, unmodified copyright notice remains
- * intact in the source code; and,
- * (c) the AUTHOR is not held responsible for fixing bugs or making
- * enhancements or changes to the SOFTWARE for any reason; and,
- * (d) the SOFTWARE is not redistributed if it is modified in any way; and,
- * (e) otherwise comply with the terms of this agreement; and,
- * (f) the AUTHOR is forgiven for making so many demands.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE
- * AUTHOR FURTHER DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT
- * LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS
- * FOR A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE
- * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU.
- *
- * The author can be reached at:
- * Michael McMahon
- * P.O. Box 14807
- * San Luis Nabisco, CA 93406-4807 USA
- * Internet: mmcmahon@oboe.calpoly.edu
- * [Bug reports, suggestions, success stories, etc. are welcome; tech
- * support, and other unnecessary two-way mail, is not]
- */
-
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- #include <mem.h>
- #include "general.h"
- #include "wadfile.h"
-
- /* Private wadfile variables */
- static int wadfileInitialized=FALSE; /* Module doesn't work unless TRUE */
- static WadfileMalloc wadfileMalloc; /* User's allocate memory routine */
- static WadfileFree wadfileFree; /* User's free memory routine */
- static int wadfileNumAllocations; /* Keeps track of the malloc's */
-
- /*------------------------- Private routines ------------------------------*/
-
- /**[ Internal 1 of 2 ]****************************************************
- * *
- * wf_malloc *
- * *
- * Desc: *
- * This calls the user's memory allocation routine and updates *
- * the 'wadfileNumAllocations' variable. *
- * *
- * Def: *
- * static void * wf_malloc(unsigned long size); *
- * *
- * Parm: *
- * size Number of bytes to allocate. *
- * *
- * Retn: *
- * Pointer to allocated memory, or NULL if not enough memory. *
- * *
- * Notes: *
- * This is the gateway for the WADFILE routines to access the user's *
- * memory allocation routine. Don't call 'wadfileMalloc()' directly. *
- * *
- *************************************************************************/
-
- static void * wf_malloc(unsigned long size)
- {
- void * result;
-
- /* Sanity check */
- assert(wadfileMalloc != NULL);
-
- /* Allocate memory and bump wadfileNumAllocations if successful */
- result = wadfileMalloc(size);
- if (result != NULL)
- wadfileNumAllocations++;
-
- return result;
- }
-
- /**[ Internal 2 of 2 ]****************************************************
- * *
- * wf_free *
- * *
- * Desc: *
- * This calls the user's memory de-allocation routine and updates *
- * the 'wadfileNumAllocations' variable. *
- * *
- * Def: *
- * static void wf_free(void * ptr); *
- * *
- * Parm: *
- * ptr Valid memory pointer that was allocated with wf_malloc. *
- * *
- * Retn: *
- * None *
- * *
- * Notes: *
- * This is the gateway for the WADFILE routines to access the user's *
- * memory deallocation routine. Don't call 'wadfileFree()' directly. *
- * *
- *************************************************************************/
-
- static void wf_free(void * ptr)
- {
- /* Sanity check */
- assert(wadfileFree != NULL);
-
- /* Bounds check -- wf_malloc doesn't change wadfileNumAllocations
- with a NULL value, so wf_free behaves the same way with NULL. */
- if (ptr == NULL) return;
-
- /* Free the memory and update counter */
- wadfileFree(ptr);
- wadfileNumAllocations--;
- }
-
-
- /*-------------------------- Public routines ------------------------------*/
-
- /**[ #1 ]*****************************************************************
- * *
- * WadfileAddLump *
- * *
- * Desc: *
- * This writes a lump to a Wadfile being created, and adds a *
- * directory entry associated with the lump. *
- * *
- * Def: *
- * int WadfileAddLump(Wadfile * wad, unsigned long size, *
- * char * name, char * data); *
- * *
- * Parm: *
- * wad Wadfile to add the lump data to. *
- * size Size of lump data in bytes. *
- * name Directory name of lump. IT MUST BE 8 CHARACTERS! *
- * data Pointer to lump data. *
- * *
- * Retn: *
- * TRUE if the data is added successfully, FALSE otherwise. *
- * *
- * Notes: *
- * If compiling for a 16-bit target, the maximum lump size is 64k. *
- * *
- * 'name' should consist of capital letters, numbers, and the under- *
- * score character. If the text is less than eight characters, it *
- * must be padded with zeroes. For example: "E1M1\0\0\0\0" is correct.*
- * *
- *************************************************************************/
-
- int WadfileAddLump(Wadfile * wad, unsigned long size, char * name, char * data)
- {
- unsigned long location;
- char * ptr;
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (!(wad->flags & FLAG_WADFILE_WRITEONLY)) return FALSE;
-
- /* Bump up 'entryIndex' */
- if (wad->entryIndex == INVALID_ENTRY)
- wad->entryIndex = 0;
- else
- wad->entryIndex++;
- if (wad->entryIndex >= wad->dirNumEntries) return FALSE;
-
- /* Copy data to 'dirCache' */
- location = ftell(wad->wf);
- ptr = &wad->dirCache[wad->entryIndex*SIZEOF_WAD_DIR_ENTRY];
- memcpy(ptr, &location, SIZEOF_WAD_DIR_LOCATION);
- ptr += SIZEOF_WAD_DIR_LOCATION;
- memcpy(ptr, &size, SIZEOF_WAD_DIR_SIZE);
- ptr += SIZEOF_WAD_DIR_SIZE;
- memcpy(ptr, name, SIZEOF_WAD_DIR_NAME);
-
- /* Write data to Wadfile on disk */
- if (size != 0)
- fwrite(data, size, 1, wad->wf);
-
- return TRUE;
- }
-
- /**[ #2 ]*****************************************************************
- * *
- * WadfileClose *
- * *
- * Desc: *
- * This closes a Wadfile and flushes its disk cache. If the lump is *
- * open, it is closed and the lump memory is released. If the *
- * Wadfile is being created, the directory is written to disk and *
- * the file header is updated before the Wadfile is closed. *
- * *
- * Def: *
- * void WadfileClose(Wadfile * wad); *
- * *
- * Parm: *
- * wad The Wadfile to close. *
- * *
- * Retn: *
- * None. *
- * *
- *************************************************************************/
-
- void WadfileClose(Wadfile * wad)
- {
- uint32 size, location;
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* If the file is open, flush caches, close file and clear the open flag */
- if (wad->flags & FLAG_WADFILE_OPEN)
- {
- /* If creating a file, write directory entries and fix header */
- if (wad->flags & FLAG_WADFILE_WRITEONLY)
- {
- if (wad->entryIndex != INVALID_ENTRY)
- {
- /* Initialize variables */
- size = wad->entryIndex + 1;
- location = ftell(wad->wf);
-
- /* Write directory to disk */
- fwrite(wad->dirCache, SIZEOF_WAD_DIR_ENTRY, size, wad->wf);
-
- /* Fix WAD header */
- fseek(wad->wf, SIZEOF_WAD_SIGNATURE, SEEK_SET);
- fwrite(&size, sizeof(size), 1, wad->wf);
- fwrite(&location, sizeof(location), 1, wad->wf);
-
- }
- else
- {
- /* Invalid Wad file, so destroy WAD Signature */
- fseek(wad->wf, 0L, SEEK_SET);
- size = 0;
- fwrite(&size, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
- }
- }
-
- /* Flush 'dirCache' */
- if (wad->flags & FLAG_WADFILE_DIRCACHED)
- {
- wf_free(wad->dirCache);
- wad->flags ^= FLAG_WADFILE_DIRCACHED;
- }
- if (wad->flags & FLAG_LUMP_OPEN)
- WadfileLumpClose(wad);
-
- /* Close file */
- fclose(wad->wf);
- wad->flags ^= FLAG_WADFILE_OPEN;
- }
- }
-
- /**[ #3 ]*****************************************************************
- * *
- * WadfileCopyEntry *
- * *
- * Desc: *
- * This copies an arbitrary lump from an open Wadfile to a Wadfile *
- * that is being created. Do not use 'WadfileLumpOpen' or *
- * 'WadfileLumpClose' to initialize and release the lump data; this *
- * routine is self-contained and opens, copies, and closes the lump *
- * data in one fell swoop. *
- * *
- * Def: *
- * int WadfileCopyEntry(Wadfile * dest, char * destName, *
- * Wadfile * src, char * srcName) *
- * *
- * Parm: *
- * dest A Wadfile that is being created. *
- * destName The directory entry name for the new lump. *
- * src An existing Wadfile. *
- * srcName The directory entry name to search for and copy. *
- * *
- * Retn: *
- * TRUE if lump is copied succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * On a 16-bit platform, this successfully copies lumps larger *
- * than 64k. *
- * *
- *************************************************************************/
-
- int WadfileCopyEntry(Wadfile * dest, char * destName,
- Wadfile * src, char * srcName)
- {
- /* Sequentially search WAD directory for 'srcName' */
- if (!WadfileSeek(src, srcName)) return FALSE;
-
- /* Copy lump from source to destination */
- if (!WadfileLumpCopy(dest, destName, src)) return FALSE;
-
- return TRUE;
- }
-
- /**[ #4 ]*****************************************************************
- * *
- * WadfileCopyMap *
- * *
- * Desc: *
- * This copies an arbitrary map from an open Wadfile to a Wadfile *
- * that is being created. Do not use 'WadfileLumpOpen' or *
- * 'WadfileLumpClose' to initialize and release the lump data; this *
- * routine is self-contained and opens, copies, and closes the lump *
- * data in one fell swoop. *
- * *
- * Def: *
- * int WadfileCopyMap(Wadfile * dest, int destEpisode, int destMap, *
- * Wadfile * src, int srcEpisode, int srcMap) *
- * *
- * Parm: *
- * dest A Wadfile that is being created. *
- * destEpisode The new episode number for the map data. *
- * destMap The new map number for the map data. *
- * src An existing Wadfile. *
- * srcEpisode The old episode number for the map data. *
- * srcMap The old map number for the map data. *
- * *
- * Retn: *
- * TRUE if map is copied succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * On a 16-bit platform, this successfully copies lumps larger *
- * than 64k. *
- * *
- *************************************************************************/
-
- int WadfileCopyMap(Wadfile * dest, int destEpisode, int destMap,
- Wadfile * src, int srcEpisode, int srcMap)
- {
- int i;
- char targetName[SIZEOF_WAD_DIR_NAME];
-
- /* Seek to map location, if possible */
- if (!WadfileSeekMap(src, srcEpisode, srcMap)) return FALSE;
-
- /* Copy the source map to destination map */
- if (!WadfileLumpOpen(src)) return FALSE;
- sprintf(targetName, "E%dM%d\0\0\0\0", destEpisode, destMap);
- if (!WadfileAddLump(dest, src->lumpSize, targetName, src->lumpData))
- return FALSE;
- if (!WadfileLumpClose(src)) return FALSE;
-
- /* Now that this is copied, go to next entry */
- WadfileGetNextDirInfo(src);
-
- /* Write out all other sections of the map */
- for (i=0; i<NUM_ENTRIES_PER_MAP-1; i++)
- {
- /* Copy lump from source to destination */
- if (!WadfileLumpCopy(dest, src->entryName, src))
- return FALSE;
-
- /* Go to next entry in the directory */
- WadfileGetNextDirInfo(src);
- }
-
- return TRUE;
- }
-
- /**[ #5 ]*****************************************************************
- * *
- * WadfileCreate *
- * *
- * Desc: *
- * This initializes a Wadfile structure, and creates a WAD file on *
- * disk. This file can be either an IWAD or a PWAD file. *
- * *
- * Def: *
- * int WadfileCreate(Wadfile * wad, char * filename, *
- * int type, int maxEntries); *
- * *
- * Parm: *
- * wad The Wadfile to create. *
- * filename The filename (with path) to use. *
- * type The file type, either IWAD or PWAD: *
- * TYPE_IWAD Create an IWAD file. *
- * TYPE_PWAD Create a PWAD file. *
- * maxEntries The maximum number of directory entries that can be *
- * used in this Wadfile. *
- * *
- * Retn: *
- * TRUE if the Wadfile is created successfully, FALSE otherwise. *
- * *
- * Notes: *
- * If 'filename' exists on disk, the function fails. YOU must delete *
- * the file before calling this function. *
- * *
- * 'filename' should have a ".WAD" extension. *
- * *
- * There is no reason to create an IWAD file. You should always *
- * create a PWAD file. *
- * *
- * Be liberal when choosing 'maxEntries'. You have less RAM is you *
- * choose too high, the program crashes if you choose too low. Each *
- * entry takes 16 bytes of RAM. The registered DOOM has just over *
- * 2000 entries. *
- * *
- *************************************************************************/
-
- int WadfileCreate(Wadfile * wad, char * filename, int type, int maxEntries)
- {
- uint32 longint;
- char s[SIZEOF_WAD_SIGNATURE+1];
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (filename == NULL) return FALSE;
- if ((type != TYPE_IWAD) && (type != TYPE_PWAD)) return FALSE;
- if (maxEntries <= 0) return FALSE;
-
- /* Make sure the memory allocation routines exist */
- if (wadfileMalloc == NULL) return FALSE;
-
- /* Initialize WAD structure */
- wad->flags = 0;
- wad->dirNumEntries = maxEntries;
- wad->entryIndex = INVALID_ENTRY;
- wad->entryName[SIZEOF_WAD_DIR_NAME] = 0; /* Permanent end of string mark */
- wad->dirCache = NULL;
-
- /* Make sure the file doesn't already exist */
- wad->wf = fopen(filename, "rb");
- if (wad->wf!=NULL) return FALSE;
-
- /* Create the file, return if error */
- wad->wf = fopen(filename, "wb");
- if (wad->wf==NULL) return FALSE;
- wad->flags ^= FLAG_WADFILE_OPEN;
- wad->flags ^= FLAG_WADFILE_WRITEONLY;
-
- /* Write signature to the Wadfile */
- if (type==TYPE_IWAD)
- strcpy(s, IWAD_SIGNATURE);
- else
- strcpy(s, PWAD_SIGNATURE);
- s[SIZEOF_WAD_SIGNATURE] = 0;
- fwrite(s, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
-
- /* Write out dummy values for dir location and size as placeholders */
- longint=0;
- fwrite(&longint, sizeof(longint), 1, wad->wf);
- fwrite(&longint, sizeof(longint), 1, wad->wf);
-
- /* Create the directory with 'maxEntries' number of entries */
- wad->dirCache = wf_malloc(maxEntries*SIZEOF_WAD_DIR_ENTRY);
- if (wad->dirCache == NULL)
- {
- WadfileClose(wad);
- return FALSE;
- }
- wad->flags |= FLAG_WADFILE_DIRCACHED;
-
- return TRUE;
- }
-
- /**[ #6 ]*****************************************************************
- * *
- * WadfileGetDirInfo *
- * *
- * Desc: *
- * This loads a specific Wadfile directory entry into a Wadfile *
- * structure. *
- * *
- * Def: *
- * int WadfileGetDirInfo(Wadfile * wad, int entryIndex); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * entryIndex Directory index to load in. *
- * *
- * Retn: *
- * TRUE if entry found and loaded succesfully; FALSE otherwise. *
- * *
- *************************************************************************/
-
- int WadfileGetDirInfo(Wadfile * wad, int entryIndex)
- {
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (entryIndex < 0) return FALSE;
- if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (entryIndex > wad->dirNumEntries) return FALSE;
-
- /* Copy info from memory or disk */
- if (wad->flags & FLAG_WADFILE_DIRCACHED)
- {
- /* From memory cache */
- memcpy(&wad->entryLocation, &wad->dirCache[entryIndex*SIZEOF_WAD_DIR_ENTRY], SIZEOF_WAD_DIR_ENTRY);
- }
- else
- {
- /* Seek to the correct directory entry and read it in from disk */
- fseek(wad->wf, wad->dirLocation + SIZEOF_WAD_DIR_ENTRY*entryIndex, SEEK_SET);
- fread(&wad->entryLocation, SIZEOF_WAD_DIR_ENTRY, 1, wad->wf);
- }
-
- /* Update WAD structure */
- wad->entryIndex = entryIndex;
-
- return TRUE;
- }
-
- /**[ #7 ]*****************************************************************
- * *
- * WadfileGetNextDirInfo *
- * *
- * Desc: *
- * This loads the next Wadfile directory entry into a Wadfile *
- * structure. *
- * *
- * Def: *
- * int WadfileGetNextDirInfo(Wadfile * wad); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * *
- * Retn: *
- * TRUE if entry loaded succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * This routine fails if you haven't called 'WadfileGetDirInfo' at *
- * least once with this Wadfile variable. *
- * *
- *************************************************************************/
-
- int WadfileGetNextDirInfo(Wadfile * wad)
- {
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- return WadfileGetDirInfo(wad, wad->entryIndex+1);
- }
-
- /**[ #8 ]*****************************************************************
- * *
- * WadfileGetPrevDirInfo *
- * *
- * Desc: *
- * This loads the previous Wadfile directory entry into a Wadfile *
- * structure. *
- * *
- * Def: *
- * int WadfileGetPrevDirInfo(Wadfile * wad); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * *
- * Retn: *
- * TRUE if entry loaded succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * This routine fails if you haven't called 'WadfileGetDirInfo' at *
- * least once with this Wadfile variable. *
- * *
- *************************************************************************/
-
- int WadfileGetPrevDirInfo(Wadfile * wad)
- {
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- return WadfileGetDirInfo(wad, wad->entryIndex-1);
- }
-
-
- /**[ #9 ]*****************************************************************
- * *
- * WadfileInitialize *
- * *
- * Desc: *
- * This initializes the Wadfile support and must be called before *
- * any other Wadfile routines are called. *
- * *
- * Def: *
- * int WadfileInitialize(WadfileMalloc * wfm, WadfileFree * wff); *
- * *
- * Parm: *
- * wfm Malloc routine for Wadfile routines (can be NULL) *
- * wff Free memory routine for Wadfile routines (can be NULL) *
- * *
- * Retn: *
- * TRUE if the memory routines are operational, FALSE otherwise. *
- * *
- * Notes: *
- * Either both of the parameters are NULL or not. It is a fatal error *
- * to specify one routine and not the other. *
- * *
- * Any time you want to specify different memory allocation routines *
- * for the Wadfile library, just call this routine again. If there *
- * are lingering allocations, the function will fail. *
- * *
- *************************************************************************/
-
- int WadfileInitialize(WadfileMalloc wfm, WadfileFree wff)
- {
- /* Bounds check--vital enough to be asserts */
- assert(((wfm==NULL) && (wff==NULL))||
- ((wfm!=NULL) && (wff!=NULL)));
-
- /* See if we're getting re-initialized */
- if (wadfileInitialized)
- {
- /* Any lingering allocations? */
- if (wadfileNumAllocations)
- wadfileInitialized = FALSE;
- else
- {
- /* No? Re-initialize. */
- wadfileMalloc = wfm;
- wadfileFree = wff;
- }
- }
- else
- {
- /* Make sure the compiler understands the code */
- assert(sizeof(int16) == 2);
- assert(sizeof(uint16) == 2);
- assert(sizeof(int32) == 4);
- assert(sizeof(uint32) == 4);
-
- /* Initialize the memory handlers */
- wadfileNumAllocations = 0;
- wadfileMalloc = wfm;
- wadfileFree = wff;
-
- wadfileInitialized = TRUE;
- }
-
- return wadfileInitialized;
- }
-
- /**[ #10 ]****************************************************************
- * *
- * WadfileLumpClose *
- * *
- * Desc: *
- * This releases the memory allocated to the lump that is stored *
- * in a Wadfile structure. This memory is allocated and filled *
- * by the 'WadfileLumpOpen' routine. *
- * *
- * Def: *
- * int WadfileLumpClose(Wadfile * wad); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * *
- * Retn: *
- * TRUE if lump memory freed succesfully; FALSE otherwise. *
- * *
- *************************************************************************/
-
- int WadfileLumpClose(Wadfile * wad)
- {
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (wadfileMalloc==NULL) return FALSE;
- if (!(wad->flags & FLAG_LUMP_OPEN)) return FALSE;
-
- /* Deallocate the LUMP data */
- if (wad->lumpSize != 0)
- wf_free(wad->lumpData);
-
- /* Update Wadfile structure */
- wad->flags ^= FLAG_LUMP_OPEN;
-
- return TRUE;
- }
-
- /**[ #11 ]****************************************************************
- * *
- * WadfileLumpCopy *
- * *
- * Desc: *
- * This copies the lump data from an open Wadfile to a Wadfile that *
- * is being created. Do not use 'WadfileLumpOpen' or *
- * 'WadfileLumpClose' to initialize and release the lump data; this *
- * routine is self-contained and opens, copies, and closes the lump *
- * data in one fell swoop. *
- * *
- * Def: *
- * int WadfileLumpCopy(Wadfile * dest, char * destName, Wadfile * src); *
- * *
- * Parm: *
- * dest A Wadfile that is being created. *
- * destName The directory entry name for the new lump. *
- * src An existing Wadfile. *
- * *
- * Retn: *
- * TRUE if lump is copied succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * On a 16-bit platform, this successfully copies lumps larger *
- * than 64k. *
- * *
- *************************************************************************/
-
- int WadfileLumpCopy(Wadfile * dest, char * destName, Wadfile * src)
- {
- unsigned long allocSize;
- unsigned long lumpCopySize;
- unsigned long location;
- char * ptr;
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (wadfileMalloc==NULL) return FALSE;
- if (!(dest->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (!(src->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (!(dest->flags & FLAG_WADFILE_WRITEONLY)) return FALSE;
- if (src->flags & FLAG_WADFILE_WRITEONLY) return FALSE;
- if (dest->flags & FLAG_LUMP_OPEN) return FALSE;
- if (src->entryIndex == INVALID_ENTRY) return FALSE;
- if (destName == NULL) return FALSE;
-
- /* Set LUMP variables */
- dest->lumpLocation = src->entryLocation;
- dest->lumpSize = src->entrySize;
- memcpy(dest->lumpName, destName, SIZEOF_WAD_DIR_NAME);
- location = ftell(dest->wf);
-
- /* Seek to start of data to be read */
- fseek(src->wf, src->entryLocation, SEEK_SET);
-
- /* Set up loop control variable */
- lumpCopySize = dest->lumpSize;
-
- /* Do the copy */
- while (lumpCopySize != 0)
- {
- /* Allocate a buffer */
- if (lumpCopySize >= MALLOC_MAX)
- allocSize = MALLOC_MAX;
- else
- allocSize = lumpCopySize;
- dest->lumpData = wf_malloc(allocSize);
- if (dest->lumpData == NULL) return FALSE;
-
- /* Read LUMP data from 'src' and write to 'dest' */
- fread(dest->lumpData, allocSize, 1, src->wf);
- fwrite(dest->lumpData, allocSize, 1, dest->wf);
-
- /* Free the buffer */
- wf_free(dest->lumpData);
-
- /* Update our byte count */
- lumpCopySize -= allocSize;
- } /* while */
-
- /* Bump up 'entryIndex' */
- if (dest->entryIndex == INVALID_ENTRY)
- dest->entryIndex = 0;
- else
- dest->entryIndex++;
- if (dest->entryIndex >= dest->dirNumEntries) return FALSE;
-
- /* Copy data to 'dirCache' */
- ptr = &dest->dirCache[dest->entryIndex*SIZEOF_WAD_DIR_ENTRY];
- memcpy(ptr, &location, SIZEOF_WAD_DIR_LOCATION);
- ptr += SIZEOF_WAD_DIR_LOCATION;
- memcpy(ptr, &dest->lumpSize, SIZEOF_WAD_DIR_SIZE);
- ptr += SIZEOF_WAD_DIR_SIZE;
- memcpy(ptr, dest->lumpName, SIZEOF_WAD_DIR_NAME);
-
- return TRUE;
- }
-
- /**[ #12 ]****************************************************************
- * *
- * WadfileLumpOpen *
- * *
- * Desc: *
- * This allocates memory and reads in the lump associated with the *
- * current directory entry in the Wadfile structure. The memory *
- * is released later on by using the 'WadfileLumpClose' routine. *
- * *
- * Def: *
- * int WadfileLumpOpen(Wadfile * wad); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * *
- * Retn: *
- * TRUE if lump allocated and read in succesfully; FALSE otherwise. *
- * *
- * Notes: *
- * This routine fails if you haven't called 'WadfileGetDirInfo' at *
- * least once with this Wadfile variable. *
- * *
- * If you're using a 16-bit compiler, the maximum lump size is 64k. *
- * This function fails if the lump is too big. Only 1 lump out of *
- * 2045 in the registered version of DOOM is >64kb. (E2M7 SIDEDEFS) *
- * Use 'WadfileLumpCopy' to work around the 64k limitation. *
- * *
- *************************************************************************/
-
- int WadfileLumpOpen(Wadfile * wad)
- {
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds check */
- if (wadfileMalloc==NULL) return FALSE;
- if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (wad->flags & FLAG_WADFILE_WRITEONLY) return FALSE;
- if (wad->flags & FLAG_LUMP_OPEN) return FALSE;
- if (wad->entryIndex == INVALID_ENTRY) return FALSE;
-
- /* Allocate memory for LUMP */
- if (wad->entrySize != 0)
- {
- wad->lumpData = wf_malloc(wad->entrySize);
- if (wad->lumpData == NULL) return FALSE;
- }
-
- /* Set LUMP variables */
- wad->lumpLocation = wad->entryLocation;
- wad->lumpSize = wad->entrySize;
- memcpy(wad->lumpName, wad->entryName, SIZEOF_WAD_DIR_NAME);
-
- /* Read LUMP data from disk */
- if (wad->lumpSize != 0)
- {
- fseek(wad->wf, wad->entryLocation, SEEK_SET);
- fread(wad->lumpData, wad->lumpSize, 1, wad->wf);
- }
-
- /* Update Wadfile structure */
- wad->flags |= FLAG_LUMP_OPEN;
-
- return TRUE;
- }
-
- /**[ #13 ]****************************************************************
- * *
- * WadfileOpen *
- * *
- * Desc: *
- * This opens a WAD file and initializes a Wadfile context. *
- * *
- * Def: *
- * int WadfileOpen(Wadfile * wad, char * filename, int type); *
- * *
- * Parm: *
- * wad The Wadfile context *
- * filename The file name (including path) of the WAD file. *
- * type The type of WAD file to open: *
- * WANTIWAD accept only IWAD files. *
- * WANTPWAD accept only PWAD files. *
- * IWADPWAD accept either IWAD or PWAD files. *
- * *
- * Retn: *
- * TRUE if the file exists and is open, FALSE otherwise. *
- * *
- *************************************************************************/
-
- int WadfileOpen(Wadfile * wad, char * filename, int type)
- {
- uint32 longint;
- char s[SIZEOF_WAD_SIGNATURE+1];
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Initialize WAD structure */
- wad->flags = 0;
- wad->entryIndex = INVALID_ENTRY;
- wad->entryName[SIZEOF_WAD_DIR_NAME] = 0; /* Permanent end of string mark */
- wad->dirCache = NULL;
-
- /* Open the file, return if error */
- wad->wf = fopen(filename, "rb");
- if (wad->wf==NULL) return FALSE;
- wad->flags ^= FLAG_WADFILE_OPEN;
-
- /* Read in and check the WAD file signature */
- fread(s, SIZEOF_WAD_SIGNATURE, 1, wad->wf);
- s[SIZEOF_WAD_SIGNATURE] = 0;
- if (strcmp(s, IWAD_SIGNATURE) == 0)
- wad->flags |= FLAG_WADFILE_IWAD;
- else
- if (strcmp(s, PWAD_SIGNATURE) != 0)
- goto Exit_Error;
-
- /* Read in directory location and size */
- fread(&longint, sizeof(longint), 1, wad->wf);
- wad->dirNumEntries = longint;
- fread(&longint, sizeof(longint), 1, wad->wf);
- wad->dirLocation = longint;
-
- /* Make sure the file type matches what the caller is asking for */
- if (((type == WANTPWAD)&&(wad->flags & FLAG_WADFILE_IWAD)) ||
- ((type == WANTIWAD)&&(!(wad->flags & FLAG_WADFILE_IWAD))))
- {
- Exit_Error:
- WadfileClose(wad);
- return FALSE;
- }
-
- /* If memory allocation is available, try to cache the directory */
- if (wadfileMalloc != NULL)
- {
- wad->dirCache = wf_malloc(wad->dirNumEntries*SIZEOF_WAD_DIR_ENTRY);
- if (wad->dirCache != NULL)
- {
- wad->flags |= FLAG_WADFILE_DIRCACHED;
- fseek(wad->wf, wad->dirLocation, SEEK_SET);
- fread(wad->dirCache, wad->dirNumEntries*SIZEOF_WAD_DIR_ENTRY,
- 1,wad->wf);
- }
- }
-
- return TRUE;
- }
-
- /**[ #14 ]****************************************************************
- * *
- * WadfileSeek *
- * *
- * Desc: *
- * This routine does a linear search through the Wadfile's directory *
- * starting with the first directory entry and searching until it *
- * finds its target or hits the end of the directory. *
- * *
- * Def: *
- * int WadfileSeek(Wadfile * wad, char * targetName); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * targetName The name of the target directory entry. *
- * *
- * Retn: *
- * TRUE if target was found succesfully; FALSE otherwise. *
- * If TRUE, then the Wadfile's 'entryIndex', 'entryName', *
- * 'entrySize', and 'entryLocation' contain meaningful values. *
- * *
- * Notes: *
- * 'targetName' can be less than 8 characters; that is, you do not *
- * have to pad it with zeroes, like in 'WadfileAddLump'. *
- * *
- * See also 'WadfileSeekMap' if you are looking for a specific map. *
- * *
- *************************************************************************/
-
- int WadfileSeek(Wadfile * wad, char * targetName)
- {
- int i;
- char targetString[SIZEOF_WAD_DIR_NAME+1];
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Convert target name to a null-terminated string */
- strncpy(targetString, targetName, SIZEOF_WAD_DIR_NAME);
- targetString[SIZEOF_WAD_DIR_NAME] = '\0';
-
- /* Bounds Check */
- if (!(wad->flags & FLAG_WADFILE_OPEN)) return FALSE;
- if (targetString == NULL) return FALSE; /* Too small */
- if (strlen(targetString)>SIZEOF_WAD_DIR_NAME) return FALSE; /* Too big */
-
- /* Begin linear search of the WAD directory */
- i=0;
- while ((i<wad->dirNumEntries)&&(strcmp(wad->entryName, targetString) !=0))
- {
- WadfileGetDirInfo(wad, i);
- i++;
- }
-
- return (i<wad->dirNumEntries);
- }
-
- /**[ #15 ]****************************************************************
- * *
- * WadfileSeekMap *
- * *
- * Desc: *
- * This routine does a linear search through the Wadfile's directory *
- * starting with the first directory entry and searching until it *
- * finds its target map or hits the end of the directory. *
- * *
- * Def: *
- * int WadfileSeekMap(Wadfile * wad, int episodeNum, int mapNum); *
- * *
- * Parm: *
- * wad The Wadfile structure to process. *
- * episodeNum Episode to find. Valid range is 1...DOOM_LASTEPISODE. *
- * mapNum Map to find. Valid range is 1...DOOM_LASTMAP. *
- * *
- * Retn: *
- * TRUE if target was found succesfully; FALSE otherwise. *
- * If TRUE, then the Wadfile's 'entryIndex', 'entryName', *
- * 'entrySize', and 'entryLocation' contain meaningful values. *
- * *
- * Notes: *
- * This routine uses 'WadfileSeek' as its search engine. When you *
- * aren't looking for maps, use 'WadfileSeek'. *
- * *
- *************************************************************************/
-
- int WadfileSeekMap(Wadfile * wad, int episodeNum, int mapNum)
- {
- char targetName[5];
-
- /* Make sure WadfileInitialize has been called */
- assert(wadfileInitialized);
-
- /* Bounds Check */
- if ((episodeNum < 0) || (episodeNum > DOOM_LASTEPISODE)) return FALSE;
- if ((mapNum < 0) || (mapNum > DOOM_LASTMAP)) return FALSE;
-
- /* Compose directory name */
- sprintf(targetName, "E%dM%d",episodeNum, mapNum);
-
- /* Sequentially search WAD directory for ExMy */
- return WadfileSeek(wad, targetName);
- }
-
-
-